import java.io.IOException;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
/****
 * Doesn't write to the location
 */

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Laurens
 */
public class Replace_Error_With_Temp_Refactor implements RefactoringMethod
{
    /*
     * Initialization and declaration of variables
     */
    int lineNumber = 0;
    FileEditor fileE = new FileEditor();
    String type = " ";
    String packageName = "";
    /*
     * End of initialization and declaration of variables
     */
    
    /**
     * Default constructor, DOES NOTHING
     */
    public Replace_Error_With_Temp_Refactor()
    {
        //DOES NOTHING
    }
    
    /**
     * Does the replace error with temp refactoring
     * @param parameters
     * @return
     */
    @Override
    public Vector<String> refactor(Vector<String> parameters)
    {
        /*
         * Calls all the parameters needed to complete rename refactor
         */
        try 
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } 
        catch (Exception ex) 
        {
            Logger.getLogger(Rename_Parameter_Refactor.class.getName()).log(Level.SEVERE, null, ex);
        } 
        String path = "";  
        String option = "";
        String className = "";
        String classN = "";
        Vector<String> result = new Vector<String>();
        if(parameters.size() > 0)
        {
            path = parameters.get(0);
            String lineNumberString = JOptionPane.showInputDialog("Please enter the linenumber which you would like to replace?");
            lineNumber = Integer.parseInt(lineNumberString);
            StringTokenizer stClassName = new StringTokenizer(path, "/");
            while(stClassName.hasMoreTokens())
            {
                className = stClassName.nextToken();
            }
            StringTokenizer st = new StringTokenizer(className, ".");
            classN = st.nextToken();
            result.add(path);
            option = JOptionPane.showInputDialog("(1) inLine (2) new Class?\n");
            String file = "";
            try
            {
                /*
                 * Reads the file needed to rename refactor
                 */
                file = fileE.read(path);
                int max_Length = getLength(file);
                if(max_Length < lineNumber)
                {
                    result.add("Error, that number is greater than the file size, not allowed.");
                    return result;
                }
                boolean checkValid = checkValidReplaceLine(file);
                if(!checkValid)
                {
                    result.add("Error, you cannot replace this line with an exception");
                    return result;
                }
                Introduce_Local_Extension_Refactor n = new Introduce_Local_Extension_Refactor();
                n.getPackage(file);
            }
            catch(Exception e)
            {

            }
            if("1".equals(option))
            {
                result.add(replaceErrorWithTempInLine(file, lineNumber));
            }
            else if("2".equals(option))
            {
                type = getType(file);
                System.out.println(type);
                try 
                {
                    result.add(replaceErrorWithTempNewClass(file, lineNumber, classN)); 
                } 
                catch (IOException ex) 
                {
                    Logger.getLogger(Replace_Error_With_Temp_Refactor.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            else
            {
                result.add("Error!");
                return result;
            }
        }
        return result;
    }

    /**
     * Replaces the line that contains the error with a throw statement
     * @param file
     * @param lineNumber
     * @return 
     */
    public String replaceErrorWithTempInLine(String file, int lineNumber) 
    {
        Scanner scanner = new Scanner(file);
        int i = 1;
        Vector<String> result = new Vector<String>();
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            if(i == lineNumber)
            {
                result.add("\tthrow new UnsupportedOperationException(\"Not yet implemented\");");
            }
            else
            {
                result.add(currentLine);
            }
            i++;
        }
        String output = "";
        for(int u = 0; u < result.size(); u++)
        {
            output += result.get(u) + "\n";
        }
        return output;
    }
    
    /**
     * Replaces the line that contains the error with a throw statement
     * @param file
     * @param lineNumber
     * @return 
     */
    public String replaceErrorWithTempNewClass(String file, int lineNumber, String classN) throws IOException 
    {
        Scanner scanner = new Scanner(file);
        int i = 1;
        Vector<String> result = new Vector<String>();
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            if(i == lineNumber)
            {
                System.out.println("asjasdk");
                System.out.println(type);
                result.add("\tClassException"+classN+" _"+classN+" = new ClassException"+classN+"();");
                result.add("\treturn "+"_"+classN+"."+"exceptionMethod"+classN+"();");
            }
            else
            {
                result.add(currentLine);
            }
            i++;
        }
        String className = "ClassException"+classN;
        String methodName = "exceptionMethod"+classN+"()";
        createNewClass(className, methodName);
        String output = "";
        for(int u = 0; u < result.size(); u++)
        {
            output += result.get(u) + "\n";
        }
        return output;
    }

    public void createNewClass(String className, String methodName) throws IOException 
    {
        Vector<String> result = new Vector<String>();
        result.add("\n");
        result.add("package " + packageName);
        result.add("\n");
        result.add("public class " + className + " extends Exception");
        result.add("{");
        result.add("\tpublic " + className + "()");
        result.add("\t{");
        result.add("\n");
        result.add("\t}");
        result.add("\tpublic " + type + methodName);
        result.add("\t{");
        result.add("\tthrow new UnsupportedOperationException(\"Not yet implemented\");");
        result.add("\t}");
        result.add("}");
        String output = " ";
        for(int y = 0; y < result.size(); y++)
        {
            output += result.get(y) + "\n";
        }
        fileE.write(className, output);
    }
    
    public String getType(String file)
    {
        Scanner scanner = new Scanner(file);
        int i = 1;
        String _type = "";
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            if(i < lineNumber)
            {
                if(currentLine.contains("public "))
                {
                    _type = getT(currentLine);
                }
                else if(currentLine.contains(" public "))
                {
                    _type = getT(currentLine);
                }
                else if(currentLine.contains("private "))
                {
                    _type = getT(currentLine);
                }
                else if(currentLine.contains(" private "))
                {
                    getT(currentLine);
                }
            }
            i++;
        }        
        return _type;
    }

    private String getT(String currentLine) 
    {
        StringTokenizer st = new StringTokenizer(currentLine," ");
        while(st.hasMoreTokens())
        {
            String current = st.nextToken();
            if(current.equals("public"))
            {
                if(current.equals("abstract"))
                {
                    
                }
                else
                {
                    return st.nextToken()+" ";
                }
            }
            else if(current.equals("private"))
            {
                if(current.equals("abstract"))
                {
                    
                }
                else
                {
                    return st.nextToken()+" ";
                }
            }
        }
        return "";
    }

    /**
     * Returns a description of the current refactoring method
     * @return 
     */
    @Override
    public String description() 
    {
        return "Replaces error code with a throw statement.";
    }

    /**
     * Gets the length of the file
     * @param file
     * @return 
     */
    public int getLength(String file) 
    {
        Scanner scanner = new Scanner(file);
        int result = 1;
        while(scanner.hasNext())
        {
            scanner.nextLine();
            result++;
        }
        return result;
    }

    /**
     * Checks if the line could be replaced with a exception
     * @param file
     * @return 
     */
    public boolean checkValidReplaceLine(String file) 
    {
        Scanner scanner = new Scanner(file);
        boolean result = false;
        boolean found = false;
        int i = 1;
        while(!found)
        {
            String currentLine = scanner.nextLine();
            if(i == lineNumber)
            {
                if(currentLine.contains("return "))
                {
                    result = true;
                }
                found = true;
            }
            i++;
        }
        return result;
    }
}

